﻿import QtQuick 2.12
import QtQuick.Layouts 1.13
import QtQuick.Shapes 1.13
import QtQuick.Particles 2.13
import QtQuick.Controls 2.5
import QtBluetooth 5.13

// 导入自定义包
import com.mycompany.customType 1.0

ApplicationWindow {
    id: mainWindow
    visible: true
    width: 300
    height: 480
    title: qsTr("蓝牙测试")

    // 别名
    property alias logEdit: logForm.logEdit
    property alias receiveEdit: sendReceiveForm.receiveEdit
    property alias sendEdit: sendReceiveForm.sendEdit

    // 字体加载
    FontLoader {
        id: customFont;
        source: "/font/SourceHanSansCN-Normal.otf"
    }
    // 设置字体,默认字体中文显示有问题
    font{family: customFont.name; pixelSize: 14}

    Component.onCompleted: {
        //logForm.log("ApplicationWindow onCompleted. " + btModel + " " + btSocket)
    }
    Component.onDestruction: {
        //logForm.log("ApplicationWindow onDestruction")
    }

    Connections{
        target: BluetoothCtrlSingleton
        onSignalBluetoothState: {
            //console.log("newState:" + newState);
            switch(newState){
            case BluetoothCtrlSingleton.BluetoothState_NoScan:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr(""));
                break;
                // ------------------------------------------------------
            case BluetoothCtrlSingleton.BluetoothState_localConnected:
                break;
            case BluetoothCtrlSingleton.BluetoothState_localDisconnected:
                bluetoothStatus.text = "蓝牙：<font color=\"red\">未连接</font>";
                break;
                // ------------------------------------------------------
            case BluetoothCtrlSingleton.BluetoothState_DeviceStart:
                searchForm.searchBtn.text = qsTr("停止设备搜索");
                showStatusMsg(qsTr("正在扫描蓝牙设备"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_DeviceNewDiscovered:
                showStatusMsg(qsTr("找到新蓝牙设备"), 1000);
                break;
            case BluetoothCtrlSingleton.BluetoothState_DeviceEnd:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("扫描蓝牙设备结束"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_DeviceCancel:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("取消扫描蓝牙设备"));
                break;
                // ------------------------------------------------------
            case BluetoothCtrlSingleton.BluetoothState_ServiceStart:
                searchForm.searchBtn.text = qsTr("停止服务搜索");
                showStatusMsg(qsTr("正在扫描蓝牙服务"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_ServiceNewDiscovered:
                showStatusMsg(qsTr("找到新蓝牙服务"), 1000);
                break;
            case BluetoothCtrlSingleton.BluetoothState_ServiceEnd:
                showStatusMsg(qsTr("扫描蓝牙服务结束"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_ServiceEndAllDevice:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr(""));
                break;
            case BluetoothCtrlSingleton.BluetoothState_ServiceCancel:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("取消扫描蓝牙服务"));
                break;
                // ------------------------------------------------------
            case BluetoothCtrlSingleton.BluetoothState_SocketConnected:
                showStatusMsg(qsTr("<font color=\"green\">Socket已连接</font>"));
                bluetoothStatus.text = "蓝牙：<font color=\"green\">已连接</font>"
                swipeView.setCurrentIndex(1)
                break;
            case BluetoothCtrlSingleton.BluetoothState_SocketDisconnected:
                showStatusMsg(qsTr("<font color=\"red\">Socket连接断开</font>"));
                bluetoothStatus.text = "蓝牙：<font color=\"red\">未连接</font>"
                break;
                // ------------------------------------------------------
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyConnectStart:
                showStatusMsg(qsTr("<font color=\"green\">低功耗蓝牙开始连接</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyConnected:
                showStatusMsg(qsTr("<font color=\"green\">低功耗蓝牙已连接</font>"));
                bluetoothStatus.text = "蓝牙：<font color=\"green\">已连接</font>"
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyDisconnected:
                showStatusMsg(qsTr("<font color=\"green\">低功耗蓝牙已断开</font>"));
                bluetoothStatus.text = "蓝牙：<font color=\"red\">未连接</font>"
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyDiscoverServiceStart:
                showStatusMsg(qsTr("正查找低功耗蓝牙服务"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyDiscoverNewService:
                showStatusMsg(qsTr("找到低功耗蓝牙服务"), 1000);
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyDiscoverDetails:
                showStatusMsg(qsTr("查找低功耗蓝牙服务详细内容"), 1000);
                break;

                // ---------------------------------------------------------------
                //----------------------------------------------------------------
                // localBluetooth错误
            case BluetoothCtrlSingleton.BluetoothState_LocalBluetoothPairingError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙配对失败</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LocalBluetoothUnknownError:
                showStatusMsg(qsTr("<font color=\"red\">本地蓝牙未知错误</font>"));
                break;
                // DeviceDiscoveryAgent错误和ServiceDiscoveryAgent错误
            case BluetoothCtrlSingleton.BluetoothState_InputOutputError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">蓝牙IO错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_PoweredOffError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">本地蓝牙已关闭</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_InvalidBluetoothAdapterError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">无效蓝牙适配器</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_UnsupportedPlatformError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">不支持当前平台</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_UnsupportedDiscoveryMethod:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">不支持的查找方法</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_DeviceDiscoveryAgentUnknownError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">查找蓝牙设备未知错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_BluetoothServiceUnknownError:
                searchForm.searchBtn.text = qsTr("搜索");
                showStatusMsg(qsTr("<font color=\"red\">查找蓝牙服务未知错误</font>"));
                break;
                // socket错误
            case BluetoothCtrlSingleton.BluetoothState_UnknownSocketError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙socket未知错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_RemoteHostClosedError:
                showStatusMsg(qsTr("<font color=\"red\">远端蓝牙socket已关闭</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_HostNotFoundError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙主机不存在</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_ServiceNotFoundError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙服务不存在，可能需要手动配对蓝牙</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_NetworkError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙网络错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_UnsupportedProtocolError:
                showStatusMsg(qsTr("<font color=\"red\">不支持的蓝牙协议</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_OperationError:
                showStatusMsg(qsTr("<font color=\"red\">蓝牙socket操作错误</font>"));
                break;
                // LowEnergyController错误
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlUnknownError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙未知错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlUnknownRemoteDeviceError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙未知远端错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlNetworkError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙网络错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlInvalidBluetoothAdapterError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙无效蓝牙适配器</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlConnectionError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙连接错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlAdvertisingError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙广播错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyCtrlRemoteHostClosedError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗蓝牙远端设备已关闭</font>"));
                break;
                // LowEnergyService错误
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceOperationError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗服务操作错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceCharacteristicWriteError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗Characteristic写入错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceDescriptorWriteError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗Descriptor写入错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceUnknownError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗服务未知错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceCharacteristicReadError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗Characteristic读错误</font>"));
                break;
            case BluetoothCtrlSingleton.BluetoothState_LowEnergyServiceDescriptorReadError:
                showStatusMsg(qsTr("<font color=\"red\">低功耗Descriptor读错误</font>"));
                break;
            }
        }
    }
    // 接收数据信号
    property int rxByteCount: 0
    property int txByteCount: 0
    Connections{
        target: BluetoothCtrlSingleton
        onSignalReceiveData:{
            //byteArray;
            //showStatusMsg(qsTr("收到新数据"));
            //receiveEdit.append(byteArray);
            //receiveEdit.insert(receiveEdit.length, byteArray);
        }
    }
    Connections{
        target: BluetoothCtrlSingleton
        onSignalReceiveString:{
            //byteArray;
            showStatusMsg(qsTr("收到新数据"));
            //receiveEdit.append(byteArray);
            receiveEdit.insert(receiveEdit.length, strData);
        }
    }
    Connections{
        target: BluetoothCtrlSingleton
        onSignalReceiveByteLength:{
            rxByteCount += byteLength;
            sendReceiveForm.labelRxByteCount.text = rxByteCount;
        }
    }
    Connections{
        target: BluetoothCtrlSingleton
        onSignalSendByteLength:{
            txByteCount += byteLength;
            sendReceiveForm.labelTxByteCount.text = txByteCount;
        }
    }

    // 本地蓝牙信息窗口
    DialogLocalBluetoothInfo {
        id: dialogLocalBluetooth
    }

    // 工具栏
    header: ToolBar {
        contentHeight: toolButton.implicitHeight

        ToolButton {
            id: toolButton
            text: ""
            icon.source: "/image/menuBtn.png"
            display: AbstractButton.IconOnly
            font.pixelSize: Qt.application.font.pixelSize * 1.6
            onClicked: {
                drawer.open()
            }
        }
        /*
        Label {
            //text: stackView.currentItem.title
            anchors.centerIn: parent
        }
        */
        TabBar {
            id: tabBar
            anchors.right: parent.right
            anchors.left: toolButton.right
            //width: parent.width * 0.8
            currentIndex: swipeView.currentIndex

            TabButton {
                text: qsTr("搜索")
            }
            TabButton {
                text: qsTr("收发")
            }
            TabButton {
                text: qsTr("日志")
            }
        }
    }
    // 抽屉式菜单
    Drawer {
        id: drawer
        width: Math.max(mainWindow.width * 0.5, 100)
        height: mainWindow.height

        Column {
            anchors.fill: parent

            ItemDelegate {
                text: qsTr("本地蓝牙")
                width: parent.width
                onClicked: {
                    dialogLocalBluetooth.setInfo(BluetoothCtrlSingleton.getLocalDeviceInfo());
                    dialogLocalBluetooth.open();
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("清空接收")
                width: parent.width
                onClicked: {
                    receiveEdit.clear();
                    swipeView.setCurrentIndex(1);
                    rxByteCount = 0;
                    sendReceiveForm.labelRxByteCount.text = rxByteCount;
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("清空发送")
                width: parent.width
                onClicked: {
                    sendEdit.clear();
                    swipeView.setCurrentIndex(1);
                    txByteCount = 0;
                    sendReceiveForm.labelTxByteCount.text = txByteCount;
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("清空日志")
                width: parent.width
                onClicked: {
                    logEdit.clear();
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("关于")
                width: parent.width
                onClicked: {
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("退出")
                width: parent.width
                onClicked: {
                    Qt.quit()
                    drawer.close()
                }
            }
            /*
            ItemDelegate {
                text: qsTr("qml搜索蓝牙")
                width: parent.width
                onClicked: {
                    btModel.discoveryMode = BluetoothDiscoveryModel.FullServiceDiscovery
                    btModel.running = true
                    logForm.log("discovery:" + btModel.running + ",connect:" + btSocket.connected);
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("qml发送")
                width: parent.width
                onClicked: {
                    if(btSocket.connected){
                        var sendData = sendEdit.text;
                        if(sendData.length > 0)
                        {
                            btSocket.stringData = sendData;
                        }
                    }
                    drawer.close()
                }
            }
            */
        }
    }
    /*
        BusyIndicator {
            id: busyIndicatorID
            parent: Overlay.overlay
            anchors.centerIn: mainWindow
            running: false
        }*/

    // 主区域
    SwipeView {
        id: swipeView
        anchors.fill: parent
        interactive: false
        currentIndex: tabBar.currentIndex

        Search{
            id: searchForm
        }
        SendReceive{
            id: sendReceiveForm
        }
        Log{
            id: logForm
        }
        //
        onCurrentIndexChanged: {
        }
    }
    // 状态栏状态消息函数
    function showStatusMsg(msg, timeoutMs)
    {
        statusBarMsgCtrl.text = msg
        if(msg.length <= 0)
        {
            statusBarMsgCtrlTimer.stop();
            return ;
        }
        if(arguments.length == 1)
        {// 只有一个参数
            statusBarMsgCtrlTimer.interval = 10000;
            statusBarMsgCtrlTimer.restart();
        }
        else if(arguments.length == 2)
        {
            if(timeoutMs > 0)
            {
                statusBarMsgCtrlTimer.interval = timeoutMs
            }
            statusBarMsgCtrlTimer.restart();
        }
    }
    // 状态栏
    footer: ToolBar {
        height: 20
        leftPadding: 5
        rightPadding: 5
        background: Rectangle{
            anchors.fill: parent
            color: "white"
            border.width: 1
            border.color: "black"

            // 使用矩形覆盖其他边框
            Rectangle{
                color: parent.color
                border.width: 0
                anchors.fill: parent
                anchors.topMargin: 1
                anchors.rightMargin: 0
                anchors.bottomMargin: 0
                anchors.leftMargin: 0
            }
            /*
            // 绘制一条边框
            Shape {
                anchors.fill: parent
                ShapePath {
                    strokeWidth: 0
                    strokeColor: "black"
                    strokeStyle: ShapePath.SolidLine
                    startX: 0; startY: 0
                    PathLine { x: mainWindow.width; y: 0 }
                }
            }
            */
        }

        Label{
            id: statusBarMsgCtrl
            height: parent.height
            verticalAlignment: Text.AlignVCenter
            text: ""
            Timer {
                id: statusBarMsgCtrlTimer
                interval: 10000
                running: false
                repeat: false
                onTriggered: statusBarMsgCtrl.text = ""
            }
        }

        Label{
            id: bluetoothStatus
            height: parent.height
            anchors.right: parent.right
            verticalAlignment: Text.AlignVCenter
            text: "蓝牙：<font color=\"red\">未连接</font>"
        }
        Label{
            text: "  "
        }

    }


    /////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////
    // 蓝牙搜索
    BluetoothDiscoveryModel {
        id: btModel
        running: false
        discoveryMode: BluetoothDiscoveryModel.FullServiceDiscovery
        remoteAddress: "20:18:08:30:41:20"
        //remoteAddress: "00:15:87:21:0F:1D"

        onDiscoveryModeChanged: {
            logForm.log("Discovery mode: " + discoveryMode)
        }
        onRunningChanged: {
            logForm.log("Discovery run changed: " + running)
        }
        onDeviceDiscovered:{
            logForm.log("New device: " + device)
        }
        onServiceDiscovered:{
            logForm.log("Found new service,deviceAddress:" + service.deviceAddress + ",deviceName:" + service.deviceName + ",serviceName:" + service.serviceName + ",serviceDescription:" + service.serviceDescription + ",serviceProtocol:" + service.serviceProtocol + ",serviceUuid:" + service.serviceUuid);
            if(service.serviceName == "Serial Port Profile")
            {
                btSocket.service = service
                btSocket.connected = true
            }
        }
        onErrorChanged: {
            switch (btModel.error) {
            case BluetoothDiscoveryModel.PoweredOffError:
                logForm.log("Error: Bluetooth device not turned on"); break;
            case BluetoothDiscoveryModel.InputOutputError:
                logForm.log("Error: Bluetooth I/O Error"); break;
            case BluetoothDiscoveryModel.InvalidBluetoothAdapterError:
                logForm.log("Error: Invalid Bluetooth Adapter Error"); break;
            case BluetoothDiscoveryModel.NoError:
                break;
            default:
                logForm.log("Error: Unknown Error"); break;
            }
        }
    }
    // 蓝牙连接
    BluetoothSocket{
        id: btSocket
        connected: false

        onConnectedChanged: {
            logForm.log("onConnectedChanged:" +  connected);
            bluetoothStatus.text = connected?"蓝牙：<font color=\"green\">已连接</font>":"蓝牙：<font color=\"red\">未连接</font>"
        }
        onErrorChanged: {
            switch (btSocket.error) {
                //case BluetoothSocket.NoError: logForm.log("Error: NoError");break
            case BluetoothSocket.UnknownSocketError:
                logForm.log("Error: UnknownSocketError"); break;
            case BluetoothSocket.HostNotFoundError:
                logForm.log("Error: HostNotFoundError"); break;
            case BluetoothSocket.ServiceNotFoundError:
                logForm.log("Error: ServiceNotFoundError"); break;
            case BluetoothSocket.NetworkError:
                logForm.log("Error: NetworkError"); break;
            case BluetoothSocket.UnsupportedProtocolError:
                logForm.log("Error: UnsupportedProtocolError"); break;
            case BluetoothSocket.RemoteHostClosedError:
                logForm.log("Error: RemoteHostClosedError"); break;

            default:
                logForm.log("Error: Unknown Error：" + btSocket.error); break;
            }
        }

        onStateChanged: {
            switch (btSocket.state) {
            case BluetoothSocket.NoServiceSet:
                logForm.log("state: NoServiceSet"); break;
            case BluetoothSocket.Unconnected:
                logForm.log("state: Unconnected"); break;
            case BluetoothSocket.ServiceLookup:
                logForm.log("state: ServiceLookup"); break;
            case BluetoothSocket.Connecting:
                logForm.log("state: Connecting"); break;
            case BluetoothSocket.Connected:
                logForm.log("state: Connected"); break;
            case BluetoothSocket.Closing:
                logForm.log("state: Closing"); break;
            case BluetoothSocket.Listening:
                logForm.log("state: Listening"); break;
            case BluetoothSocket.Bound:
                logForm.log("state: Bound"); break;
            default:
                logForm.log("Unknown state：" + btSocket.state); break;
            }
        }
        onStringDataChanged: {
            var data = btSocket.stringData;
            if(data.length <= 0)
            {
                return ;
            }
            logForm.log("onStringDataChanged:len:" + data.length + ", data:" + data);
            //receiveEdit.append(data);
        }
    }
}
